Trò chơi Angry Birds trong UNITY Engine
31.685 lượt xem;
1 using UnityEngine;
2 using System;
3 using System.Collections;
4 using System.Collections.Generic;
5
6
7 /// <summary>
8 /// base class shared by the Tween and TweenChain classes to allow a seemless API when controlling
9 /// either of them
10 /// </summary>
11 public abstract class AbstractGoTween
12 {
13 public int id = 0; // optional id used for identifying this tween
14 public GoTweenState state { get; protected set; } // current state of the tween
15 public float duration { get; protected set; } // duration for a single loop
16 public float totalDuration { get; protected set; } // duration for all loops of this tween
17 public float timeScale { get; set; } // time scale to be used by this tween
18
19 public GoUpdateType updateType { get; protected set; }
20 public GoLoopType loopType { get; protected set; }
21 public int iterations { get; protected set; } // set to -1 for infinite
22
23 public bool autoRemoveOnComplete { get; set; } // should we automatically remove ourself from the Go's list of tweens when done?
24 public bool isReversed { get; protected set; } // have we been reversed? this is different than a PingPong loop's backwards section
25 public bool allowEvents { get; set; } // allow the user to surpress events.
26 protected bool _didInit; // flag to ensure event only gets fired once
27 protected bool _didBegin; // flag to ensure event only gets fired once
28 protected bool _fireIterationStart;
29 protected bool _fireIterationEnd;
30
31 // internal state for update logic
32 protected float _elapsedTime; // elapsed time for the current loop iteration
33 protected float _totalElapsedTime; // total elapsed time of the entire tween
34 public float totalElapsedTime { get { return _totalElapsedTime; } }
35
36 protected bool _isLoopingBackOnPingPong;
37 public bool isLoopingBackOnPingPong { get { return _isLoopingBackOnPingPong; } }
38
39 protected bool _didIterateLastFrame;
40 protected bool _didIterateThisFrame;
41 protected int _deltaIterations; // change in completed iterations this frame.
42 protected int _completedIterations;
43 public int completedIterations { get { return _completedIterations; } }
44
45 // action event handlers
46 protected Action<AbstractGoTween> _onInit; // executes before initial setup.
47 protected Action<AbstractGoTween> _onBegin; // executes when a tween starts.
48 protected Action<AbstractGoTween> _onIterationStart; // executes whenever a tween starts an iteration.
49 protected Action<AbstractGoTween> _onUpdate; // execute whenever a tween updates.
50 protected Action<AbstractGoTween> _onIterationEnd; // executes whenever a tween ends an iteration.
51 protected Action<AbstractGoTween> _onComplete; // exectures whenever a tween completes
52
53 public void setOnInitHandler( Action<AbstractGoTween> onInit )
54 {
55 _onInit = onInit;
56 }
57
58 public void setOnBeginHandler( Action<AbstractGoTween> onBegin )
59 {
60 _onBegin = onBegin;
61 }
62
63 public void setonIterationStartHandler( Action<AbstractGoTween> onIterationStart )
64 {
65 _onIterationStart = onIterationStart;
66 }
67
68 public void setOnUpdateHandler( Action<AbstractGoTween> onUpdate )
69 {
70 _onUpdate = onUpdate;
71 }
72
73 public void setonIterationEndHandler( Action<AbstractGoTween> onIterationEnd )
74 {
75 _onIterationEnd = onIterationEnd;
76 }
77
78 public void setOnCompleteHandler( Action<AbstractGoTween> onComplete )
79 {
80 _onComplete = onComplete;
81 }
82
83 /// <summary>
84 /// called once per tween when it is first updated
85 /// </summary>
86 protected virtual void onInit()
87 {
88 if( !allowEvents )
89 return;
90
91 if( _onInit != null )
92 _onInit( this );
93
94 _didInit = true;
95 }
96
97 /// <summary>
98 /// called whenever the tween is updated and the playhead is at the start (or end, depending on isReversed) of the tween.
99 /// </summary>
100 protected virtual void onBegin()
101 {
102 if( !allowEvents )
103 return;
104
105 if( isReversed && _totalElapsedTime != totalDuration )
106 return;
107 else if( !isReversed && _totalElapsedTime != 0f )
108 return;
109
110 if( _onBegin != null )
111 _onBegin( this );
112
113 _didBegin = true;
114 }
115
116
117 /// <summary>
118 /// called once per iteration at the start of the iteration.
119 /// </summary>
120 protected virtual void onIterationStart()
121 {
122 if( !allowEvents )
123 return;
124
125 if( _onIterationStart != null )
126 _onIterationStart( this );
127 }
128
129 /// <summary>
130 /// called once per update, after the update has occured.
131 /// </summary>
132 protected virtual void onUpdate()
133 {
134 if( !allowEvents )
135 return;
136
137 if( _onUpdate != null )
138 _onUpdate( this );
139 }
140
141 /// <summary>
142 /// called once per iteration at the end of the iteration.
143 /// </summary>
144 protected virtual void onIterationEnd()
145 {
146 if( !allowEvents )
147 return;
148
149 if( _onIterationEnd != null )
150 _onIterationEnd( this );
151 }
152
153
154 /// <summary>
155 /// called when the tween completes playing.
156 /// </summary>
157 protected virtual void onComplete()
158 {
159 if( !allowEvents )
160 return;
161
162 if( _onComplete != null )
163 _onComplete( this );
164 }
165
166
167 /// <summary>
168 /// tick method. if it returns true it indicates the tween is complete.
169 /// note: at it's base, AbstractGoTween does not fire events, it is up to the implementer to
170 /// do so. see GoTween and AbstractGoTweenCollection for examples.
171 /// </summary>
172 public virtual bool update( float deltaTime )
173 {
174 // increment or decrement the total elapsed time then clamp from 0 to totalDuration
175 if( isReversed )
176 _totalElapsedTime -= deltaTime;
177 else
178 _totalElapsedTime += deltaTime;
179
180 _totalElapsedTime = Mathf.Clamp( _totalElapsedTime, 0, totalDuration );
181
182 _didIterateLastFrame = _didIterateThisFrame || ( !isReversed && _totalElapsedTime == 0 ) || ( isReversed && _totalElapsedTime == totalDuration );
183
184 // we flip between ceil and floor based on the direction, because we want the iteration change
185 // to happen when "duration" seconds has elapsed, not immediately, as was the case if you
186 // were doing a floor and were going in reverse.
187 if( isReversed )
188 _deltaIterations = Mathf.CeilToInt( _totalElapsedTime / duration ) - _completedIterations;
189 else
190 _deltaIterations = Mathf.FloorToInt( _totalElapsedTime / duration ) - _completedIterations;
191
192 // we iterated this frame if we have done a goTo() to an iteration point, or we've passed over
193 // an iteration threshold.
194 _didIterateThisFrame = !_didIterateLastFrame && ( _deltaIterations != 0f || _totalElapsedTime % duration == 0f );
195
196 _completedIterations += _deltaIterations;
197
198 // set the elapsedTime, given what we know.
199 if( _didIterateLastFrame )
200 {
201 _elapsedTime = isReversed ? duration : 0f;
202 }
203 else if( _didIterateThisFrame )
204 {
205 // if we iterated this frame, we force the _elapsedTime to the end of the timeline.
206 _elapsedTime = isReversed ? 0f : duration;
207 }
208 else
209 {
210 _elapsedTime = _totalElapsedTime % duration;
211
212 // if you do a goTo(x) where x is a multiple of duration, we assume that you want
213 // to be at the end of your duration, as this sets you up to have an automatic OnIterationStart fire
214 // the next updated frame. the only caveat is when you do a goTo(0) when playing forwards,
215 // or a goTo(totalDuration) when playing in reverse. we assume that at that point, you want to be
216 // at the start of your tween.
217 if( _elapsedTime == 0f && ( ( isReversed && _totalElapsedTime == totalDuration ) || ( !isReversed && _totalElapsedTime > 0f ) ) )
218 {
219 _elapsedTime = duration;
220 }
221 }
222
223 // we can only be looping back on a PingPong if our loopType is PingPong and we are on an odd numbered iteration
224 _isLoopingBackOnPingPong = false;
225 if( loopType == GoLoopType.PingPong )
226 {
227 // due to the way that we count iterations, and force a tween to remain at the end
228 // of it's timeline for one frame after passing the duration threshold,
229 // we need to make sure that _isLoopingBackOnPingPong references the current
230 // iteration, and not the next one.
231 if( isReversed )
232 {
233 _isLoopingBackOnPingPong = _completedIterations % 2 == 0;
234
235 if( _elapsedTime == 0f )
236 _isLoopingBackOnPingPong = !_isLoopingBackOnPingPong;
237 }
238 else
239 {
240 _isLoopingBackOnPingPong = _completedIterations % 2 != 0;
241
242 if( _elapsedTime == duration )
243 _isLoopingBackOnPingPong = !_isLoopingBackOnPingPong;
244 }
245 }
246
247 // set a flag whether to fire the onIterationEnd event or not.
248 _fireIterationStart = _didIterateThisFrame || ( !isReversed && _elapsedTime == duration ) || ( isReversed && _elapsedTime == 0f );
249 _fireIterationEnd = _didIterateThisFrame;
250
251 // check for completion
252 if( ( !isReversed && iterations >= 0 && _completedIterations >= iterations ) || ( isReversed && _totalElapsedTime <= 0 ) )
253 state = GoTweenState.Complete;
254
255 if( state == GoTweenState.Complete )
256 {
257 // these variables need to be reset here. if a tween were to complete,
258 // and then get played again:
259 // * The onIterationStart event would get fired
260 // * tweens would flip their elapsedTime between 0 and totalDuration
261
262 _fireIterationStart = false;
263 _didIterateThisFrame = false;
264
265 return true; // true if complete
266 }
267
268 return false; // false if not complete
269 }
270
271
272 /// <summary>
273 /// subclasses should return true if they are a valid and ready to be added to the list of running tweens
274 /// or false if not ready.
275 /// technically, this should be marked as internal
276 /// </summary>
277 public abstract bool isValid();
278
279
280 /// <summary>
281 /// attempts to remove the tween property returning true if successful
282 /// technically, this should be marked as internal
283 /// </summary>
284 public abstract bool removeTweenProperty( AbstractTweenProperty property );
285
286
287 /// <summary>
288 /// returns true if the tween contains the same type (or propertyName) property in its property list
289 /// technically, this should be marked as internal
290 /// </summary>
291 public abstract bool containsTweenProperty( AbstractTweenProperty property );
292
293
294 /// <summary>
295 /// returns a list of all the TweenProperties contained in the tween and all its children (if it is
296 /// a TweenChain or a TweenFlow)
297 /// technically, this should be marked as internal
298 /// </summary>
299 public abstract List<AbstractTweenProperty> allTweenProperties();
300
301
302 /// <summary>
303 /// removes the Tween from action and cleans up its state
304 /// </summary>
305 public virtual void destroy()
306 {
307 state = GoTweenState.Destroyed;
308 }
309
310
311 /// <summary>
312 /// pauses playback
313 /// </summary>
314 public virtual void pause()
315 {
316 state = GoTweenState.Paused;
317 }
318
319
320 /// <summary>
321 /// resumes playback
322 /// </summary>
323 public virtual void play()
324 {
325 state = GoTweenState.Running;
326 }
327
328
329 /// <summary>
330 /// plays the tween forward. if it is already playing forward has no effect
331 /// </summary>
332 public void playForward()
333 {
334 if( isReversed )
335 reverse();
336
337 play();
338 }
339
340
341 /// <summary>
342 /// plays the tween backwards. if it is already playing backwards has no effect
343 /// </summary>
344 public void playBackwards()
345 {
346 if( !isReversed )
347 reverse();
348
349 play();
350 }
351
352
353 /// <summary>
354 /// resets the tween to the beginning, taking isReversed into account.
355 /// </summary>
356 protected virtual void reset( bool skipDelay = true )
357 {
358 goTo( isReversed ? totalDuration : 0, skipDelay );
359
360 _fireIterationStart = true;
361 }
362
363
364 /// <summary>
365 /// rewinds the tween to the beginning (or end, depending on isReversed) and pauses playback.
366 /// </summary>
367 public virtual void rewind( bool skipDelay = true )
368 {
369 reset( skipDelay );
370 pause();
371 }
372
373
374 /// <summary>
375 /// rewinds the tween to the beginning (or end, depending on isReversed) and starts playback,
376 /// optionally skipping delay (only relevant for Tweens).
377 /// </summary>
378 public void restart( bool skipDelay = true )
379 {
380 reset( skipDelay );
381 play();
382 }
383
384
385 /// <summary>
386 /// reverses playback. if going forward it will be going backward after this and vice versa.
387 /// </summary>
388 public virtual void reverse()
389 {
390 isReversed = !isReversed;
391
392 _completedIterations = isReversed ? Mathf.CeilToInt( _totalElapsedTime / duration ) : Mathf.FloorToInt( _totalElapsedTime / duration );
393
394 // if we are at the "start" of the timeline, based on isReversed,
395 // allow the onBegin/onIterationStart callbacks to fire again.
396 if( ( isReversed && _totalElapsedTime == totalDuration ) || ( !isReversed && _totalElapsedTime == 0f ) )
397 {
398 _didBegin = false;
399 _fireIterationStart = true;
400 }
401 }
402
403
404 /// <summary>
405 /// completes the tween. sets the playhead to it's final position as if the tween completed normally.
406 /// takes into account if the tween was playing forward or reversed.
407 /// </summary>
408 public virtual void complete()
409 {
410 if( iterations < 0 )
411 return;
412
413 // set full elapsed time and let the next iteration finish it off
414 goTo( isReversed ? 0 : totalDuration, true );
415 }
416
417
418 /// <summary>
419 /// goes to the specified time clamping it from 0 to the total duration of the tween. if the tween is
420 /// not playing it can optionally be force updated to the time specified. delays are not taken into effect.
421 /// (must be implemented by inherited classes.)
422 /// </summary>
423 public abstract void goTo( float time, bool skipDelay = true );
424
425 /// <summary>
426 /// goes to the time and starts playback skipping any delays
427 /// </summary>
428 public void goToAndPlay( float time, bool skipDelay = true )
429 {
430 goTo( time, skipDelay );
431 play();
432 }
433
434
435 /// <summary>
436 /// waits for either completion or destruction. call in a Coroutine and yield on the return
437 /// </summary>
438 public IEnumerator waitForCompletion()
439 {
440 while( state != GoTweenState.Complete && state != GoTweenState.Destroyed )
441 yield return null;
442
443 yield break;
444 }
445 }
2 using System;
3 using System.Collections;
4 using System.Collections.Generic;
5
6
7 /// <summary>
8 /// base class shared by the Tween and TweenChain classes to allow a seemless API when controlling
9 /// either of them
10 /// </summary>
11 public abstract class AbstractGoTween
12 {
13 public int id = 0; // optional id used for identifying this tween
14 public GoTweenState state { get; protected set; } // current state of the tween
15 public float duration { get; protected set; } // duration for a single loop
16 public float totalDuration { get; protected set; } // duration for all loops of this tween
17 public float timeScale { get; set; } // time scale to be used by this tween
18
19 public GoUpdateType updateType { get; protected set; }
20 public GoLoopType loopType { get; protected set; }
21 public int iterations { get; protected set; } // set to -1 for infinite
22
23 public bool autoRemoveOnComplete { get; set; } // should we automatically remove ourself from the Go's list of tweens when done?
24 public bool isReversed { get; protected set; } // have we been reversed? this is different than a PingPong loop's backwards section
25 public bool allowEvents { get; set; } // allow the user to surpress events.
26 protected bool _didInit; // flag to ensure event only gets fired once
27 protected bool _didBegin; // flag to ensure event only gets fired once
28 protected bool _fireIterationStart;
29 protected bool _fireIterationEnd;
30
31 // internal state for update logic
32 protected float _elapsedTime; // elapsed time for the current loop iteration
33 protected float _totalElapsedTime; // total elapsed time of the entire tween
34 public float totalElapsedTime { get { return _totalElapsedTime; } }
35
36 protected bool _isLoopingBackOnPingPong;
37 public bool isLoopingBackOnPingPong { get { return _isLoopingBackOnPingPong; } }
38
39 protected bool _didIterateLastFrame;
40 protected bool _didIterateThisFrame;
41 protected int _deltaIterations; // change in completed iterations this frame.
42 protected int _completedIterations;
43 public int completedIterations { get { return _completedIterations; } }
44
45 // action event handlers
46 protected Action<AbstractGoTween> _onInit; // executes before initial setup.
47 protected Action<AbstractGoTween> _onBegin; // executes when a tween starts.
48 protected Action<AbstractGoTween> _onIterationStart; // executes whenever a tween starts an iteration.
49 protected Action<AbstractGoTween> _onUpdate; // execute whenever a tween updates.
50 protected Action<AbstractGoTween> _onIterationEnd; // executes whenever a tween ends an iteration.
51 protected Action<AbstractGoTween> _onComplete; // exectures whenever a tween completes
52
53 public void setOnInitHandler( Action<AbstractGoTween> onInit )
54 {
55 _onInit = onInit;
56 }
57
58 public void setOnBeginHandler( Action<AbstractGoTween> onBegin )
59 {
60 _onBegin = onBegin;
61 }
62
63 public void setonIterationStartHandler( Action<AbstractGoTween> onIterationStart )
64 {
65 _onIterationStart = onIterationStart;
66 }
67
68 public void setOnUpdateHandler( Action<AbstractGoTween> onUpdate )
69 {
70 _onUpdate = onUpdate;
71 }
72
73 public void setonIterationEndHandler( Action<AbstractGoTween> onIterationEnd )
74 {
75 _onIterationEnd = onIterationEnd;
76 }
77
78 public void setOnCompleteHandler( Action<AbstractGoTween> onComplete )
79 {
80 _onComplete = onComplete;
81 }
82
83 /// <summary>
84 /// called once per tween when it is first updated
85 /// </summary>
86 protected virtual void onInit()
87 {
88 if( !allowEvents )
89 return;
90
91 if( _onInit != null )
92 _onInit( this );
93
94 _didInit = true;
95 }
96
97 /// <summary>
98 /// called whenever the tween is updated and the playhead is at the start (or end, depending on isReversed) of the tween.
99 /// </summary>
100 protected virtual void onBegin()
101 {
102 if( !allowEvents )
103 return;
104
105 if( isReversed && _totalElapsedTime != totalDuration )
106 return;
107 else if( !isReversed && _totalElapsedTime != 0f )
108 return;
109
110 if( _onBegin != null )
111 _onBegin( this );
112
113 _didBegin = true;
114 }
115
116
117 /// <summary>
118 /// called once per iteration at the start of the iteration.
119 /// </summary>
120 protected virtual void onIterationStart()
121 {
122 if( !allowEvents )
123 return;
124
125 if( _onIterationStart != null )
126 _onIterationStart( this );
127 }
128
129 /// <summary>
130 /// called once per update, after the update has occured.
131 /// </summary>
132 protected virtual void onUpdate()
133 {
134 if( !allowEvents )
135 return;
136
137 if( _onUpdate != null )
138 _onUpdate( this );
139 }
140
141 /// <summary>
142 /// called once per iteration at the end of the iteration.
143 /// </summary>
144 protected virtual void onIterationEnd()
145 {
146 if( !allowEvents )
147 return;
148
149 if( _onIterationEnd != null )
150 _onIterationEnd( this );
151 }
152
153
154 /// <summary>
155 /// called when the tween completes playing.
156 /// </summary>
157 protected virtual void onComplete()
158 {
159 if( !allowEvents )
160 return;
161
162 if( _onComplete != null )
163 _onComplete( this );
164 }
165
166
167 /// <summary>
168 /// tick method. if it returns true it indicates the tween is complete.
169 /// note: at it's base, AbstractGoTween does not fire events, it is up to the implementer to
170 /// do so. see GoTween and AbstractGoTweenCollection for examples.
171 /// </summary>
172 public virtual bool update( float deltaTime )
173 {
174 // increment or decrement the total elapsed time then clamp from 0 to totalDuration
175 if( isReversed )
176 _totalElapsedTime -= deltaTime;
177 else
178 _totalElapsedTime += deltaTime;
179
180 _totalElapsedTime = Mathf.Clamp( _totalElapsedTime, 0, totalDuration );
181
182 _didIterateLastFrame = _didIterateThisFrame || ( !isReversed && _totalElapsedTime == 0 ) || ( isReversed && _totalElapsedTime == totalDuration );
183
184 // we flip between ceil and floor based on the direction, because we want the iteration change
185 // to happen when "duration" seconds has elapsed, not immediately, as was the case if you
186 // were doing a floor and were going in reverse.
187 if( isReversed )
188 _deltaIterations = Mathf.CeilToInt( _totalElapsedTime / duration ) - _completedIterations;
189 else
190 _deltaIterations = Mathf.FloorToInt( _totalElapsedTime / duration ) - _completedIterations;
191
192 // we iterated this frame if we have done a goTo() to an iteration point, or we've passed over
193 // an iteration threshold.
194 _didIterateThisFrame = !_didIterateLastFrame && ( _deltaIterations != 0f || _totalElapsedTime % duration == 0f );
195
196 _completedIterations += _deltaIterations;
197
198 // set the elapsedTime, given what we know.
199 if( _didIterateLastFrame )
200 {
201 _elapsedTime = isReversed ? duration : 0f;
202 }
203 else if( _didIterateThisFrame )
204 {
205 // if we iterated this frame, we force the _elapsedTime to the end of the timeline.
206 _elapsedTime = isReversed ? 0f : duration;
207 }
208 else
209 {
210 _elapsedTime = _totalElapsedTime % duration;
211
212 // if you do a goTo(x) where x is a multiple of duration, we assume that you want
213 // to be at the end of your duration, as this sets you up to have an automatic OnIterationStart fire
214 // the next updated frame. the only caveat is when you do a goTo(0) when playing forwards,
215 // or a goTo(totalDuration) when playing in reverse. we assume that at that point, you want to be
216 // at the start of your tween.
217 if( _elapsedTime == 0f && ( ( isReversed && _totalElapsedTime == totalDuration ) || ( !isReversed && _totalElapsedTime > 0f ) ) )
218 {
219 _elapsedTime = duration;
220 }
221 }
222
223 // we can only be looping back on a PingPong if our loopType is PingPong and we are on an odd numbered iteration
224 _isLoopingBackOnPingPong = false;
225 if( loopType == GoLoopType.PingPong )
226 {
227 // due to the way that we count iterations, and force a tween to remain at the end
228 // of it's timeline for one frame after passing the duration threshold,
229 // we need to make sure that _isLoopingBackOnPingPong references the current
230 // iteration, and not the next one.
231 if( isReversed )
232 {
233 _isLoopingBackOnPingPong = _completedIterations % 2 == 0;
234
235 if( _elapsedTime == 0f )
236 _isLoopingBackOnPingPong = !_isLoopingBackOnPingPong;
237 }
238 else
239 {
240 _isLoopingBackOnPingPong = _completedIterations % 2 != 0;
241
242 if( _elapsedTime == duration )
243 _isLoopingBackOnPingPong = !_isLoopingBackOnPingPong;
244 }
245 }
246
247 // set a flag whether to fire the onIterationEnd event or not.
248 _fireIterationStart = _didIterateThisFrame || ( !isReversed && _elapsedTime == duration ) || ( isReversed && _elapsedTime == 0f );
249 _fireIterationEnd = _didIterateThisFrame;
250
251 // check for completion
252 if( ( !isReversed && iterations >= 0 && _completedIterations >= iterations ) || ( isReversed && _totalElapsedTime <= 0 ) )
253 state = GoTweenState.Complete;
254
255 if( state == GoTweenState.Complete )
256 {
257 // these variables need to be reset here. if a tween were to complete,
258 // and then get played again:
259 // * The onIterationStart event would get fired
260 // * tweens would flip their elapsedTime between 0 and totalDuration
261
262 _fireIterationStart = false;
263 _didIterateThisFrame = false;
264
265 return true; // true if complete
266 }
267
268 return false; // false if not complete
269 }
270
271
272 /// <summary>
273 /// subclasses should return true if they are a valid and ready to be added to the list of running tweens
274 /// or false if not ready.
275 /// technically, this should be marked as internal
276 /// </summary>
277 public abstract bool isValid();
278
279
280 /// <summary>
281 /// attempts to remove the tween property returning true if successful
282 /// technically, this should be marked as internal
283 /// </summary>
284 public abstract bool removeTweenProperty( AbstractTweenProperty property );
285
286
287 /// <summary>
288 /// returns true if the tween contains the same type (or propertyName) property in its property list
289 /// technically, this should be marked as internal
290 /// </summary>
291 public abstract bool containsTweenProperty( AbstractTweenProperty property );
292
293
294 /// <summary>
295 /// returns a list of all the TweenProperties contained in the tween and all its children (if it is
296 /// a TweenChain or a TweenFlow)
297 /// technically, this should be marked as internal
298 /// </summary>
299 public abstract List<AbstractTweenProperty> allTweenProperties();
300
301
302 /// <summary>
303 /// removes the Tween from action and cleans up its state
304 /// </summary>
305 public virtual void destroy()
306 {
307 state = GoTweenState.Destroyed;
308 }
309
310
311 /// <summary>
312 /// pauses playback
313 /// </summary>
314 public virtual void pause()
315 {
316 state = GoTweenState.Paused;
317 }
318
319
320 /// <summary>
321 /// resumes playback
322 /// </summary>
323 public virtual void play()
324 {
325 state = GoTweenState.Running;
326 }
327
328
329 /// <summary>
330 /// plays the tween forward. if it is already playing forward has no effect
331 /// </summary>
332 public void playForward()
333 {
334 if( isReversed )
335 reverse();
336
337 play();
338 }
339
340
341 /// <summary>
342 /// plays the tween backwards. if it is already playing backwards has no effect
343 /// </summary>
344 public void playBackwards()
345 {
346 if( !isReversed )
347 reverse();
348
349 play();
350 }
351
352
353 /// <summary>
354 /// resets the tween to the beginning, taking isReversed into account.
355 /// </summary>
356 protected virtual void reset( bool skipDelay = true )
357 {
358 goTo( isReversed ? totalDuration : 0, skipDelay );
359
360 _fireIterationStart = true;
361 }
362
363
364 /// <summary>
365 /// rewinds the tween to the beginning (or end, depending on isReversed) and pauses playback.
366 /// </summary>
367 public virtual void rewind( bool skipDelay = true )
368 {
369 reset( skipDelay );
370 pause();
371 }
372
373
374 /// <summary>
375 /// rewinds the tween to the beginning (or end, depending on isReversed) and starts playback,
376 /// optionally skipping delay (only relevant for Tweens).
377 /// </summary>
378 public void restart( bool skipDelay = true )
379 {
380 reset( skipDelay );
381 play();
382 }
383
384
385 /// <summary>
386 /// reverses playback. if going forward it will be going backward after this and vice versa.
387 /// </summary>
388 public virtual void reverse()
389 {
390 isReversed = !isReversed;
391
392 _completedIterations = isReversed ? Mathf.CeilToInt( _totalElapsedTime / duration ) : Mathf.FloorToInt( _totalElapsedTime / duration );
393
394 // if we are at the "start" of the timeline, based on isReversed,
395 // allow the onBegin/onIterationStart callbacks to fire again.
396 if( ( isReversed && _totalElapsedTime == totalDuration ) || ( !isReversed && _totalElapsedTime == 0f ) )
397 {
398 _didBegin = false;
399 _fireIterationStart = true;
400 }
401 }
402
403
404 /// <summary>
405 /// completes the tween. sets the playhead to it's final position as if the tween completed normally.
406 /// takes into account if the tween was playing forward or reversed.
407 /// </summary>
408 public virtual void complete()
409 {
410 if( iterations < 0 )
411 return;
412
413 // set full elapsed time and let the next iteration finish it off
414 goTo( isReversed ? 0 : totalDuration, true );
415 }
416
417
418 /// <summary>
419 /// goes to the specified time clamping it from 0 to the total duration of the tween. if the tween is
420 /// not playing it can optionally be force updated to the time specified. delays are not taken into effect.
421 /// (must be implemented by inherited classes.)
422 /// </summary>
423 public abstract void goTo( float time, bool skipDelay = true );
424
425 /// <summary>
426 /// goes to the time and starts playback skipping any delays
427 /// </summary>
428 public void goToAndPlay( float time, bool skipDelay = true )
429 {
430 goTo( time, skipDelay );
431 play();
432 }
433
434
435 /// <summary>
436 /// waits for either completion or destruction. call in a Coroutine and yield on the return
437 /// </summary>
438 public IEnumerator waitForCompletion()
439 {
440 while( state != GoTweenState.Complete && state != GoTweenState.Destroyed )
441 yield return null;
442
443 yield break;
444 }
445 }